/**
 * 接口的兼容性
 * 如果传入的变量和声明的类型不匹配,TS就会进行兼容性检查.
 *  */
export { }


interface Animal {
    name: string;
    age: number;
}


interface Person {
    name: string;
    age: number;
    gender: number;
}


function getName(a: Animal): string {
    return a.name
}

let a: Animal = {
    name: '',
    age: 10
}
getName(a)

let p: Person = {
    name: '',
    age: 10,
    gender: 0
}
getName(p);

// 因为getName只校验name,所以所有包含name属性的值都可以传入其中



// 基本数据类型兼容性
let num: string | number;
let str: string = 'zhufeng';
num = str;
let num2: {
    toString(): string
}
let str2: string = 'jiagou';
num2 = str2;
// 类的兼容性-根据形状来检测是否兼容



// 函数兼容性-难点--比较参数 比较返回值(少接收可以，多接收会报错)




// 函数的协变与逆变
/**
 * A≤B 意味着A是B的子类型.
 * A→B 指的是以A为参数类型,以B为返回值类型的函数类型.
 * x:A意味着x的类型为A
 * 返回值类型时协变的,二参数类型是逆变的
 * 返回值类型可以传子类，参数可以传父类
 * 参数逆变父类  返回值协变子类 参逆父，返协子
 *
 */


class Animal {

}


class Dog extends Animal {
    public name: string = 'Dog'
}

class BlackDog extends Dog {
    public age: number = 10;
}

class WhiteDog extends Dog {
    public home: string = '北京';
}